﻿using CKS.Core.Framework.Models;
using CKS.Schedule;
using Infrastructure;
using Microsoft.AspNetCore.SignalR;
using Microsoft.Extensions.DependencyInjection;
using SqlSugar;
using SqlSugar.IOC;
using ZR.Infrastructure;
using ZR.Model.Models.ProductionControl;
using ZR.ServiceCore.Signalr;

namespace CKS.PLC.Core.CronJob
{
    [Schedule]
    public class PushJob : CronJobBase
    {
        IHubContext<MessageHub> SignalHub;
      
        IFreeSql<MesDB> fsql;
        public PushJob() : base("推送数据服务", "0/1 * * * * ?") //每间隔3秒执行1次
        {
            fsql = InternalApp.Fsql;
            
            var lst = fsql.Select<CksPartCache>().ToList();
            InitCleaingData(entraceLineDatas);
            foreach (var c in entraceLineDatas)
            {
                c.Count = lst.Find(a => a.PartType == c.DataId).CleaningLineCount.ToString();
            }

            InitCleaingData(outLineDatas);
            foreach (var c in outLineDatas)
            {
                c.Count = lst.Find(a => a.PartType == c.DataId).CacheLineCount.ToString();
            }
         

        }

        private void InitCleaingData(List<CleaningLineData> datas)
        {
            datas.Add(new CleaningLineData() { DataId = 1,Name = "翅片QXA缓存数量" });
            datas.Add(new CleaningLineData() { DataId = 2, Name = "盖板QXK缓存数量" });
            datas.Add(new CleaningLineData() { DataId = 3, Name = "底板QXM缓存数量" });
            datas.Add(new CleaningLineData() { DataId = 4, Name = "水嘴焊环QXW缓存数量" });
            datas.Add(new CleaningLineData() { DataId = 5, Name = "定位柱焊环QXZ缓存数量" });
            datas.Add(new CleaningLineData() { DataId = 6, Name = "焊丝QXX缓存数量" });
            datas.Add(new CleaningLineData() { DataId = 7, Name = "焊片QXY缓存数量" });
            datas.Add(new CleaningLineData() { DataId = 8, Name = "中板QXH缓存数量" });
            datas.Add(new CleaningLineData() { DataId = 9, Name = "接头QXN缓存数量" });
            datas.Add(new CleaningLineData() { DataId = 10, Name = "定位柱QXG缓存数量" });
        }


        /*
         需要推送清洗站数据
         定义好清洗站数据结构

         清洗线{name,count}
         */


        public List<CleaningLineData> entraceLineDatas = new List<CleaningLineData>();
        
        public List<CleaningLineData> outLineDatas = new List<CleaningLineData>();


        public SafeList<object> degrees1 = new SafeList<object>(20);
        public SafeList<object> degrees2 = new SafeList<object>(20);
        public SafeList<object> times = new SafeList<object>(20);
        /// <summary>
        /// 设备报警 key - 报警信息
        /// </summary>
        Dictionary<string,string> deviceAlarm = new Dictionary<string,string>();

        Dictionary<string, string> ageAlarm = new Dictionary<string, string>();

        private readonly object _lock = new object();
        private readonly object _lockDegree = new object();
        public void UpdateEntraceLine(CleaningLineData data)
        {
            lock (_lock)
            {
                var model = entraceLineDatas.Find(a => a.DataId == data.DataId);
                if (model == null)
                {
                    entraceLineDatas.Add(data);
                }
                else
                    model = data;
            }
        }
        /// <summary>
        /// 推送清洗线数量
        /// </summary>
        /// <param name="dataId">零件类型 == 数据ID</param>
        /// <param name="number">推送数值</param>
        public void UpdateEntraceLine(int dataId, int number)
        {
            lock (_lock)
            {
                var model = entraceLineDatas.Find(a => a.DataId == dataId);
                if (model != null)
                {
                   model.Count = number.ToString();
                }
                MRE.Set();


            }
        }
        /// <summary>
        /// 推送缓存线数量
        /// </summary>
        /// <param name="dataId">零件类型 == 数据ID</param>
        /// <param name="number">推送数值</param>
        public void UpdateOutLine(int dataId, int number)
        {
            lock (_lock)
            {
                var model = outLineDatas.Find(a => a.DataId == dataId);
                if (model != null)
                {
                    model.Count = number.ToString();
                }
                MRE.Set();


            }
        }

        

 
        ManualResetEvent MRE = new ManualResetEvent(false);
        /*
            有数据变化或者新连接时触发推送
         */
      
        protected override async Task ExecuteAsync(CancellationToken cancellationToken)
        {
            while (!cancellationToken.IsCancellationRequested) {
                try
                {
                    

                    SignalHub = InternalApp.ServiceProvider.GetService<IHubContext<MessageHub>>();
                    if (SignalHub == null)
                        return;
                    var caches = fsql.Select<CksPartCache>().OrderBy(a=>a.PartType).ToList();
                    foreach (var cache in caches)
                    {
                        entraceLineDatas.Find(a => a.DataId == cache.PartType).Count = cache.CleaningLineCount.ToString();
                        outLineDatas.Find(a => a.DataId == cache.PartType).Count = cache.CacheLineCount.ToString();
                    }

         
                    if (MessageHub.OP10Users.Count > 0)
                        await SignalHub.Clients.Clients(MessageHub.OP10Users)
                            .SendAsync("op10Receive", new { 
                                entraceLineDatas
                                , outLineDatas 
                                ,deviceAlarm = GetDeviceAlarm()
                                ,ageAlarm =  GetAgeAlarm()
                                ,caches
                            });
                    // var users = SignalHub.All.OP10Users;
                    //Debug.WriteLine($"users数量{MessageHub.OP10Users.Count}");
                    object send90 = null;
                    lock (_lockDegree)
                    {
                        send90 = new { times= times.ToArray() , degrees1=degrees1.ToArray(), degrees2=degrees2.ToArray()};
                    }
                    if (MessageHub.OP90Users.Count > 0)
                        await SignalHub.Clients.Clients(MessageHub.OP90Users).SendAsync("op90Receive", send90);





                    MRE.WaitOne(500);
                    MRE.Reset();
                }
                catch (Exception)
                {

                }
            }
        }

        public void AddDeviceAlarm(string v, string message)
        {
            lock (_lock)
            {
                deviceAlarm[v] = message;
            }
        }

        public void RemoveDeviceAlarm(string v)
        {
            lock (_lock)
            {
                deviceAlarm.Remove(v);
            }
        }

        public List<string> GetDeviceAlarm()
        {
            lock (_lock) {
                return deviceAlarm.Values.ToList();
            }
        }

        public void AddAgeAlarm(string key, string message)
        {
            lock (_lock)
            {
                ageAlarm[key] = message;
            }
        }

        public void RemoveAgeAlarm(string v)
        {
            lock (_lock)
            {
                ageAlarm.Remove(v);
                
            }
        }

       

        public List<string> GetAgeAlarm()
        {
            lock (_lock)
            {
                return ageAlarm.Values.ToList();
            }
        }
        /// <summary>
        /// 添加实时温度
        /// </summary>
        public void AddDegree(decimal degree1, decimal degree2)
        {
            lock (_lockDegree)
            {
                times.Add(DateTime.Now.ToString("HH:mm:ss"));
                degrees1.Add(degree1);
                degrees2.Add(degree2);
            }
           
        }
    }

    public class CleaningLineData
    {
        public int DataId {  get; set; }
        public string Name { get; set; }
        public string Count { get; set; } = "0";
    }
}
